package com.lizi.apidoc.handler;

import com.lizi.apidoc.constants.AnnotationName;
import com.lizi.apidoc.constants.Methods;
import com.lizi.apidoc.model.RequestBaseInfo;
import com.lizi.apidoc.utils.DocUtil;
import com.lizi.apidoc.utils.StringUtil;
import com.thoughtworks.qdox.model.JavaAnnotation;
import com.thoughtworks.qdox.model.JavaMethod;

import java.util.Arrays;
import java.util.List;

/**
 * RequestBaseInfoHandler
 * @author kingman zhangjw@3vjia.com
 * @since 2020-05-07 12:33
 */
public class RequestBaseInfoHandler {


    public static RequestBaseInfoHandler builder() {
        return new RequestBaseInfoHandler();
    }

    /**
     * handle spring request mapping
     * @param serverUrl
     * @param controllerBaseUrl
     * @param javaMethod
     * @return
     */
    public RequestBaseInfo handle(String serverUrl, String controllerBaseUrl, final JavaMethod javaMethod )
    {
        List<JavaAnnotation> annotations = javaMethod.getAnnotations();
        String url;
        String methodType = "POST";
        String shortUrl = null;
        String mediaType = null;
        boolean deprecated = false;
        int methodCounter = 0;

        for (JavaAnnotation annotation : annotations) {
            String annotationName = annotation.getType().getName();
            //注解RequestMapping中produces属性可以设置返回数据的类型以及编码,如：@RequestMapping(value="/xxx",produces = {"application/json;charset=UTF-8"})
            Object produces = annotation.getNamedParameter(AnnotationName.REQUEST_PRODUCES);
            if (produces != null) {
                mediaType = produces.toString();
            }
            Object methodParam = annotation.getNamedParameter(AnnotationName.REQUEST_METHOD);
            if (methodParam != null) {
                methodType = DocUtil.getHttpMethod(methodParam.toString());
            }
            switch (annotationName)
            {
                case AnnotationName.DEPRECATED:
                    deprecated=true;
                    break;
                case AnnotationName.REQUEST_MAPPING:
                    shortUrl = DocUtil.getRequestMappingValue(annotation);
                    methodCounter++;
                    break;
                case AnnotationName.GET_MAPPING:
                    shortUrl = DocUtil.getRequestMappingValue(annotation);
                    methodType = Methods.GET.getValue();
                    methodCounter++;
                    break;
                case AnnotationName.POST_MAPPING:
                    shortUrl = DocUtil.getRequestMappingValue(annotation);
                    methodType = Methods.POST.getValue();
                    methodCounter++;
                    break;
                case AnnotationName.PUT_MAPPING:
                    shortUrl = DocUtil.getRequestMappingValue(annotation);
                    methodType = Methods.PUT.getValue();
                    methodCounter++;
                    break;
                case AnnotationName.DELETE_MAPPING:
                    shortUrl = DocUtil.getRequestMappingValue(annotation);
                    methodType = Methods.DELETE.getValue();
                    methodCounter++;
                    break;
            }

        }
        if(methodCounter>0) {
            shortUrl = StringUtil.removeQuotes(shortUrl);
            String[] urls = shortUrl.split(",");

            url = DocUtil.getMvcUrls(serverUrl, controllerBaseUrl, Arrays.asList(urls));
            shortUrl = DocUtil.getMvcUrls("", controllerBaseUrl, Arrays.asList(urls));

            RequestBaseInfo requestMapping = RequestBaseInfo.builder()
                    .setMediaType(mediaType)
                    .setMethodType(methodType)
                    .setUrl(url)
                    .setShortUrl(shortUrl)
                    .setDeprecated(deprecated);

            return requestMapping;
        }

        return null;
    }
}
